﻿using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Net;

namespace Gmei.MdiDemo
{
    public partial class frmChild : Form
    {

        const string InLoading = "加载中...";
        const string Error = "出错了!";

        public frmChild()
        {
            InitializeComponent();
            webBrowser.ScriptErrorsSuppressed = true;
        }

        public string CurrentURL { get; set; }
        public bool IsActiveChild { get; set; }

        public override string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
                base.Text = value;
                if (MdiParent != null)
                    MdiParent.Invalidate();
            }
        }

        public WebBrowserState WebState { get; private set; }

        public void Navigate(string url)
        {
            try
            {                
                webBrowser.Navigate(url);                
            }
            catch 
            {
                Text = Error + url;
                WebState = WebBrowserState.Error;
            }
            if (IsActiveChild)
                UpdateParent();

            //异步获取网页图标
            System.Threading.ThreadPool.QueueUserWorkItem(
                new System.Threading.WaitCallback(GetIcon), url);
        }

        public void WebOperation(WebOperationType type)
        {
            switch (type)
            {
                case WebOperationType.GoBack:
                    webBrowser.GoBack();
                    break;
                case WebOperationType.GoForward:
                    webBrowser.GoForward();
                    break;
                case WebOperationType.Stop:
                    webBrowser.Stop();
                    break;
                case WebOperationType.Reflesh:
                    webBrowser.Refresh();
                    break;
            }
        }

        //获取网页的favicon
        private void GetIcon(object objUrl)
        {
            string url = objUrl as string;
            string addr;
            int beginIndex;
            if(url.StartsWith("https://"))
                beginIndex = 8;
            else
                beginIndex = 7; // http://
            int pos = url.IndexOf('/', beginIndex);
            if (pos < 0)
                addr = url + "/favicon.ico";
            else
                addr = url.Substring(0, pos) + "/favicon.ico";
            WebClient web = new WebClient();            
            Bitmap map = null;            
            try
            {
                System.IO.Stream data = web.OpenRead(addr);
                map = (Bitmap)Bitmap.FromStream(data);
                data.Close();
            }
            catch {
                Console.WriteLine("error when getting icon from " + addr);
            }
            finally
            {
                web.Dispose();
                Invoke(new Action<Bitmap>(SetFormNewIcon), new object[] { map });
            }           
        }

        //将窗体的Icon设置为网页的favicon
        private void SetFormNewIcon(Bitmap map)
        {
            if (map == null)
                return;

            var webIcon = System.Drawing.Icon.FromHandle(map.GetHicon());
            base.Icon = webIcon;
            webIcon.Dispose();
            map.Dispose();

            if (MdiParent != null)
                MdiParent.Invalidate();
        }

        private void AddViewHistoryToParent(string url, string title)
        {
            frmMain main = MdiParent as frmMain;
            if (main != null)
                main.CreateNewHistoryItem(url, title);
        }

        private void UpdateParent()
        {
            frmMain main = MdiParent as frmMain;
            if (main == null)
                return;

            main.SetTxtURL(CurrentURL);
            main.SetButtons(webBrowser.CanGoBack,
                    webBrowser.CanGoForward,
                    WebState == WebBrowserState.Loading);
        }

        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            if (webBrowser != null && !webBrowser.IsDisposed)
                webBrowser.Dispose();

            base.OnFormClosed(e);
        }



        private void frmChild_Load(object sender, EventArgs e)
        {
            
        }

        private void frmChild_Activated(object sender, EventArgs e)
        {
            UpdateParent();
            IsActiveChild = true;
        }

        private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            WebState = WebBrowserState.Complete;
            Text = webBrowser.Document.Title;
            CurrentURL = webBrowser.Document.Url.ToString();
            if (string.IsNullOrEmpty(Text))
                Text = "[无标题]";
            if (IsActiveChild)
                UpdateParent();
           
            AddViewHistoryToParent(CurrentURL, Text);
        }

        private void frmChild_Deactivate(object sender, EventArgs e)
        {
            IsActiveChild = false;
        }

        private void webBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
        {
            string url = e.Url.ToString();
            if (url.StartsWith("javascript:") || url.StartsWith("about:"))
            {
                e.Cancel = true;
                return;
            }

            CurrentURL = e.Url.ToString();
            Text = InLoading + CurrentURL;
            WebState = WebBrowserState.Loading;
            if (IsActiveChild)
                UpdateParent();            
        }

        private void webBrowser_NewWindow(object sender, System.ComponentModel.CancelEventArgs e)
        {
            bool find = false;
            string addr;

            addr = webBrowser.Document.ActiveElement.GetAttribute("href");
            if (addr.StartsWith("http"))
                find = true;
            if (!find)
            {
                addr = webBrowser.StatusText;
                if(addr.StartsWith("http"))
                    find = true;
            }

            if (find)
            {
                frmMain main = MdiParent as frmMain;
                if (main != null)
                {
                    main.GoNewWebSite(addr, true);
                    e.Cancel = true;
                }
            }            
        }
    }

    public enum WebBrowserState
    {
        Blank,
        Loading,
        Complete,
        Error,
    }

    public enum WebOperationType
    {
        GoBack,
        GoForward,
        Stop,
        Reflesh,
    }
}
